package com.googlecode.yoohoo.xep.data.protocol;

import java.util.Iterator;
import java.util.List;

import junit.framework.Assert;

import org.junit.Test;

import com.googlecode.yoohoo.xmppcore.protocol.parsing.Attribute;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.IXmppParser;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.IXmppParserFactory;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.IXmppParsingFactory;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.PredefinedXmppParsingFactory;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.ProtocolKey;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.ProtocolRelation;
import com.googlecode.yoohoo.xmppcore.protocol.parsing.XmppParserAdapter;
import com.googlecode.yoohoo.xmppcore.protocol.stanza.Iq;

public class DataParserFactoryTest {
	@Test
	public void parse() {
		String dataXml =
			"<iq type='set' id='register_2' to='192.168.1.101' xml:lang='zh_CN'>" +
				"<query xmlns='jabber:iq:register'>" +
					"<x xmlns='jabber:x:data' type='submit'>" +
						"<field type='hidden' var='FORM_TYPE'>" +
							"<value>jabber:iq:register</value>" +
						"</field>" +
						"<field type='text-single' label='用户名' var='username'>" +
							"<value>roger.yang</value>" +
						"</field>" +
						"<field type='text-private' label='口令' var='password'>" +
							"<value>password</value>" +
						"</field>" +
						"<field type='text-private' label='确认口令' var='confirmedpassword'>" +
							"<value>password</value>" +
						"</field>" +
						"<field type='text-single' label='真实姓名' var='realname'>" +
							"<value>老杨</value>" +
						"</field>" +
						"<field type='list-single' label='性别' var='x-gender'>" +
							"<value>F</value>" +
						"</field>" +
					"</x>" +
				"</query>" +
			"</iq>";
		
		IXmppParsingFactory parsingFactory = new PredefinedXmppParsingFactory();
		parsingFactory.registerParser(new RegisterParserFactory(), new ProtocolRelation(Iq.PROTOCOL_KEY, Register.PROTOCOL_KEY));
		parsingFactory.registerParser(new DataParserFactory(), new ProtocolRelation(Register.PROTOCOL_KEY, Data.PROTOCOL_KEY));
		Object object = parsingFactory.parse(dataXml);
		Iq iq = (Iq)object;
		Data data = ((Register)iq.getObject()).getData();
		
		Assert.assertEquals(DataType.SUBMIT, data.getType());
		
		Iterator<Field> iter = data.getFields().iterator();
		
		Assert.assertTrue(iter.hasNext());
		Field formType = iter.next();
		Assert.assertEquals(FieldType.HIDDEN, formType.getType());
		Assert.assertEquals("FORM_TYPE", formType.getVar());
		Assert.assertEquals(1, formType.getValues().size());
		Assert.assertEquals("jabber:iq:register", formType.getValues().get(0));
		
		Assert.assertTrue(iter.hasNext());
		Field userName = iter.next();
		Assert.assertEquals(FieldType.TEXT_SINGLE, userName.getType());
		Assert.assertEquals("username", userName.getVar());
		Assert.assertEquals("用户名", userName.getLabel());
		Assert.assertEquals(1, userName.getValues().size());
		Assert.assertEquals("roger.yang", userName.getValues().get(0));
		
		Assert.assertTrue(iter.hasNext());
		Field password = iter.next();
		Assert.assertEquals(FieldType.TEXT_PRIVATE, password.getType());
		Assert.assertEquals("password", password.getVar());
		Assert.assertEquals("口令", password.getLabel());
		Assert.assertEquals(1, password.getValues().size());
		Assert.assertEquals("password", password.getValues().get(0));
		
		Assert.assertTrue(iter.hasNext());
		Field confirmedPassword = iter.next();
		Assert.assertEquals(FieldType.TEXT_PRIVATE, confirmedPassword.getType());
		Assert.assertEquals("confirmedpassword", confirmedPassword.getVar());
		Assert.assertEquals("确认口令", confirmedPassword.getLabel());
		Assert.assertEquals(1, confirmedPassword.getValues().size());
		Assert.assertEquals("password", confirmedPassword.getValues().get(0));
		
		Assert.assertTrue(iter.hasNext());
		Field realName = iter.next();
		Assert.assertEquals(FieldType.TEXT_SINGLE, realName.getType());
		Assert.assertEquals("realname", realName.getVar());
		Assert.assertEquals("真实姓名", realName.getLabel());
		Assert.assertEquals(1, realName.getValues().size());
		Assert.assertEquals("老杨", realName.getValues().get(0));
		
		Assert.assertTrue(iter.hasNext());
		Field gender = iter.next();
		Assert.assertEquals(FieldType.LIST_SINGLE, gender.getType());
		Assert.assertEquals("x-gender", gender.getVar());
		Assert.assertEquals("性别", gender.getLabel());
		Assert.assertEquals(1, gender.getValues().size());
		Assert.assertEquals("F", gender.getValues().get(0));
	}
	
	private static class Register {
		public static final ProtocolKey PROTOCOL_KEY = new ProtocolKey("query", "jabber:iq:register");
		private Data data;
		
		public void setData(Data data) {
			this.data = data;
		}
		
		public Data getData() {
			return data;
		}
	}
	
	private class RegisterParserFactory implements IXmppParserFactory<Register> {

		@Override
		public IXmppParser<Register> createParser() {
			return new RegisterParser();
		}

		@Override
		public ProtocolKey getProtocolKey() {
			return Register.PROTOCOL_KEY;
		}		
	}
	
	private class RegisterParser extends XmppParserAdapter<Register> {
		private Register register;

		@Override
		public Register getObject() {
			return register;
		}
		
		@Override
		public void processAttributes(String path, List<Attribute> attributes) {
			register = new Register();
		}
		
		@Override
		public void processEmbeddedObject(ProtocolKey pk, Object object) {
			if (Data.PROTOCOL_KEY.equals(pk)) {
				register.setData((Data)object);
			}
		}
	}
}
